﻿using System;
using System.Collections.Generic;
using System.Text;
using RollBackLib.src.utils;
using log4net;
using System.IO;
using Microsoft.Win32;
using System.Net;

namespace RollBackLib.src.utils
{
    /// <summary>
    /// Application level settings and utilities.
    /// </summary>
    public class AppUtils
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(AppUtils));

        /// <summary>
        /// A snippet information about the currently running backup operation
        /// </summary>
        private static string m_backupRunningStatus = "";
        public static string BackupRunningStatus
        {
            get { return m_backupRunningStatus; }
            private set { }
        }

        /// <summary>
        /// Get the full path to the main settings file
        /// </summary>
        /// <returns></returns>
        public static string getSettingsFile(String root)
        {
            string mainFile = root + "\\all.xml";
            return mainFile;
        }

        /// <summary>
        /// Get the location where files/folders will be backed up.
        /// </summary>
        /// <returns></returns>
        public static string getDefaultBackupLocation(RegistryKey key)
        {
            string reg_key = "RollbackBackupLocation";
            object o = key.GetValue(reg_key);
            string path = null;
            if (o == null)
            {
                path = RollBackLib.src.sys.Sysutils.Instance.getDriveWithMaxFreeDiskspace() + "RollBack\\Backup";
                if (path != null)
                {
                    log.Info("Setting path=" + path + " as the default backup location and storing registry key <" + key.Name + "\\" + reg_key + ">");
                    key.SetValue(reg_key, path);
                }
            }
            else
            {
                if(o is string) {
                    path = (string)o;
                }
            }

            if (path == null)
            {
                log.Warn("Could not find a valid default backup path location");
            }
            else
            {
                log.Info("Using <" + path + "> as the default backup location");
            }
            return path;
        }

        /// <summary>
        /// Convert size in bytes to Human readable size like KB, MB, GB, TB
        /// </summary>
        /// <param name="sz"></param>
        /// <returns></returns>
        public static string toHumanReadableSize(long sz2)
        {
            long original = sz2;
            //decimal sz = sz2;
            Decimal sz = sz2;
            string hr = "";
            do
            {
                if (sz < 1024)
                {
                    hr = "" + sz + " bytes";
                    break;
                }
                sz /= 1024;
                if (sz < 1024)
                {
                    hr = "" + Decimal.Round(sz, 2) + " KB";
                    break;
                }
                sz /= 1024;
                if (sz < 1024)
                {
                    hr = "" + Decimal.Round(sz, 2) +" MB";
                    break;
                }
                sz /= 1024;
                if (sz < 1024)
                {
                    hr = "" + Decimal.Round(sz, 2) +" GB";
                    break;
                }
                sz /= 1024;
                if (sz < 1024)
                {
                    hr = "" + Decimal.Round(sz, 2) +" TB";
                    break;
                }
            } while (false);
            return hr;
        }

        public static string getApplicationVersion()
        {
            string version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
            return version;
        }

        /// <summary>
        /// Looks for a file in the following locations inorder and returns the path that succeeds first.
        /// </summary>
        /// <param name="fileName">The file that needs to be searched</param>
        /// <param name="paths">Any additional paths that need to be searched for the file</param>
        /// <returns></returns>
        public static string getFileResourcePath(string fileName, params string[] paths)
        {
            string fpath = "";
            List<string> newPaths = new List<string>();
            if (paths != null && paths.Length > 0)
            {
                foreach (string s in paths)
                {
                    newPaths.Add(s + "/" + fileName);
                }

            }
            // look at the relative path.
            fpath = "../../" + fileName;
            // Add two levels up from current working directory
            newPaths.Add("../../" + fileName);

            foreach (string str in newPaths)
            {
                fpath = str;
                if (File.Exists(fpath))
                {
                    return fpath;
                }
            }
            return null;
        }

        public static string getHostname()
        {
            String name = "";
            try
            {
                name = Dns.GetHostEntry(IPAddress.Loopback).HostName;
            }
            catch (Exception e)
            {
                log.Warn("Could not get hostname", e);
            }
            return name;
        }
    }
}
